package com.gw2.gw2world.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

import com.gw2.gw2world.model.Event;
import com.gw2.gw2world.model.ServerState;
import com.gw2.gw2world.model.WorldEvent;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.preference.PreferenceManager;
import android.util.SparseArray;

/** Handle event info: update status, progression
 * @author Seb
 *
 */
public class MasterEventManager {
	//@SuppressWarnings("unused")
	private static final String TAG="MasterEventManager";
	//public enum Server {HOME, GUEST1, GUEST2};
	private List<WorldEvent> master=new ArrayList<WorldEvent>(30);
	private SparseArray<String> map_names;
	private SparseArray<ServerState> servers;
	private ArrayList<Event> events=new ArrayList<Event>(400);
	private Context context;
	private SharedPreferences prefs;
	//database
	private DatabaseOpenHelper dbHelper;
	private SQLiteDatabase db;
	private Cursor c;
	private String language;
	/** The constructor load data from the database and the shared preferences:
	 * <ul>
	 * <li>server names</li>
	 * <li>map names</li>
	 * <li>master event names</li>
	 * <li>server names</li>
	 * </ul>
	 * @param ctx The activity {@link android.content.Context}
	 */
	public MasterEventManager(Context ctx) {
		context=ctx;
		prefs = PreferenceManager.getDefaultSharedPreferences(context);
		language=prefs.getString("language", "en");
		dbHelper=new DatabaseOpenHelper(context, "database", null, 1);
		dbHelper.insertWorldEvents();
		db=dbHelper.getWritableDatabase();
		getMapNames();
		getServerNames();
		getMasterEvents();
	}
	
	private void getMasterEvents() {
		c=db.query("master_event", null, "chest=1", null, null, null, null, null);
		while(c.moveToNext()) {
			WorldEvent we=new WorldEvent();
			we.id=c.getInt(0);
			we.name=context.getString(context.getResources().getIdentifier(c.getString(1), "string", context.getPackageName()));
			we.map =map_names.get(c.getInt(5));
			we.map_id=c.getInt(5);
			we.enabled=!c.isNull(7);
			master.add(we);
		}
		//get events
		c = db.query("event", null,"master IS NOT NULL",null, null, null, null, null);
		for(WorldEvent we : master) {
			//get sub events
			c = db.query("event", null,"master=?",new String[] {String.valueOf(we.id)}, null, null, null, null);
			android.util.Log.d(TAG, we.name+": "+String.valueOf(c.getCount()));
			while(c.moveToNext()) {
				Event e=null;
				for(int i=0; i<servers.size(); i++) {
					e=new Event();
					e.id   =c.getString(0);
					e.level=c.getInt(1);
					we.subevents.add(e);
					e.server_id=servers.keyAt(i);
					//android.util.Log.d(TAG, we.name+": "+String.valueOf(server_names.keyAt(i))+" "+server_names.valueAt(i));
					we.subevents.add(e);
					events.add(e);
				}
				if(e.level>1) we.eventCountBeforeMain++;
			}
			Collections.sort(we.subevents, Event.SORT_BY_DEPTH);
			we.servers2.add(new ServerState(servers.get(prefs.getInt("home_server", 0))));
			if(prefs.getInt("guest1_server", 0)>0) we.servers2.add(new ServerState(servers.get(prefs.getInt("guest1_server", 0))));
			if(prefs.getInt("guest2_server", 0)>0) we.servers2.add(new ServerState(servers.get(prefs.getInt("guest2_server", 0))));
		}
	}
	/** Get map names from the database. */
	private void getMapNames() {
		c=db.query("location", null, "lang=?", new String[]{language}, null, null, null);
		map_names=new SparseArray<String>(c.getCount());
		while(c.moveToNext())
			map_names.put(c.getInt(0), c.getString(2));
	}
	private void getServerNames() {
		StringBuilder sb=new StringBuilder();
		sb.append(prefs.getInt("home_server", 0)).append(',')
			.append(prefs.getInt("guest1_server", 0)).append(',')
			.append(prefs.getInt("guest2_server", 0));
		c=db.query("server", null, "lang=? AND id IN ("+sb.toString()+")", new String[]{language}, null, null, null);
		servers=new SparseArray<ServerState>(c.getCount());
		//android.util.Log.d(TAG, "Server count: "+String.valueOf(c.getCount()));
		ServerState ss;
		while(c.moveToNext()) {
			ss=new ServerState();
			ss.server_id=c.getInt(0);
			ss.name=c.getString(2);
			servers.append(c.getInt(0), ss);
		}
	}
	
	public void refresh(Vector<Event> l) {
		android.util.Log.d(TAG, "refresh(): Event count: "+String.valueOf(l.size()));
		for(Event r : l)
			for(Event e : events)
				if(e.id.equals(r.id) && e.server_id==r.server_id)
					e.state=r.state;
		for(WorldEvent we : master)
			we.updateProgression();
	}
	/** Tell if the master event is active: it depends on the value of {@link Event.state}
	 * @param weID WorldEvent.id
	 * @return true if active
	 */
	public boolean isMasterActivePending(int weID) {
		for(WorldEvent we : master)
			if(we.id==weID) {
				for(Event e : we.subevents)
					if(/*e.state.equals("Preparation") ||*/ e.state.equals("Active")) {
						we.active=true;
						return true;
					}
				we.active=false;
			}
		return false;
	}
	/** Count disabled server by user */
	public int getCountDisabled() {
		c=db.query("master_event", null, "repeat IS NULL", null, null, null, null, null);
		return c.getCount();
	}
	/** Count the number of unique active master events */
	public int getCountActive() {
		int n=0;
		for(WorldEvent we : master)
			if(isMasterActivePending(we.id)) n++;
		return n;
	}
	public int getCountAll() {
		return master.size()-getCountDisabled();
	}
	public int getCountDone() {
		int n=0;
		for(WorldEvent we : master)
			if(we.done) n++;
		return n;
	}

	public List<WorldEvent> getEvents(boolean showInactive) {
		return master;
	}
}
